#include<iostream>
#include<assert.h>
#include<string.h>
using namespace std;

namespace Yushen
{
  class string
  {
  public:
    typedef char* iterator;
    typedef const char* const_iterator;

    string(const char* arr = "")
    {
      _size = _capacity = strlen(arr);
      _a = new char[_capacity + 1];
      strcpy(_a, arr);
    }
    ~string()
    {
      delete[] _a;
      _a = NULL;
      _size = _capacity = 0;
    }
    void swap(string& s)
    {
      ::swap(_size, s._size);
      ::swap(_capacity, s._capacity);
      ::swap(_a, s._a);
    }
    // 拷贝构造函数 请一个帮工的
    string(const string& s)
    {
      string tmp(s._a);
      swap(tmp);
    }

    // 赋值重载
    string& operator=(string s)
    {
      swap(s);
      return *this;
    }

    // 迭代器
    iterator begin()
    {
      return _a;
    }

    iterator end()
    {
      return _a + _size;
    }

    const_iterator begin() const 
    {
      return _a;
    }

    const_iterator end() const 
    {
      return _a + _size;
    }

    // 扩容
    void reserve(int n)
    {
      if (n > _capacity)
      {
        char* tmp = new char[n + 1];
        _capacity = n;
        strcpy(tmp, _a);
        delete[] _a;
        _a = tmp;
      }
    }

    void resize(int n, char c = '\0')
    {
      if (n > _capacity)
        reserve(n);
      for (int i = _size; i < n; i++) // 比原来字符串大就增c，比原来字符串长度小，就不进入循环
        _a[i] = c;
      _a[n] = '\0';
      _size = n;
    }

    int size() const
    {
      return _size;
    }

    // 添加元素
    // 尾插
    void push_back(char c)
    {
      insert(_size, c);
    }

    // 尾插字符串
    string& append(const string& s)
    {
      insert(_size, s);
      return *this;
    }

    // 指定插入
    string& insert(int pos, char c)
    {
      assert(pos <= _size && pos >= 0);
      if (_size == _capacity)
      {
        int newcapacity = _size == 0? 4 : _capacity * 2;
        reserve(newcapacity);
      }

      memcpy(_a + pos + 1, _a + pos, sizeof(char) * (_size - pos + 1));  // +1是为了把最后的\0也拷贝进去
      _a[pos] = c;
      _size++;
      return *this;
    }

    string& insert(int pos, const string& s)
    {
      assert(pos <= _size && pos >= 0);
      int n = s._size;
      if (_size + n >  _capacity)
      {
        int newcapacity = _size + n;
        reserve(newcapacity);
      }

      memcpy(_a + pos + n, _a + pos, sizeof(char) * (_size - pos + 1));
      int i = pos, j = 0;
      while(j < n)
        _a[i++] = s[j++];
      _size += n;

      return *this;
    }

    // 指定删除
    string& erase(int pos, int len)
    {
      assert(pos >= 0 && pos < _size && len > 0);
      int n = _size - pos - len;
      if (n <= 0)
      {
        _a[pos] = '\0';
        _size = pos;
      }
      else 
      {
        memcpy(_a + pos, _a + pos + len, sizeof(char) * (n + 1));  // 不要忘了最后的\0
        _size -= len;
      }

      return *this;
    }

    // 寻找子串
    int find(char c, int pos = 0) const
    {
      assert(pos >= 0 && pos < _size);
      int i = pos;
      while(i < _size)
      {
        if (_a[i] == c)
          return i;
        i++;
      }
      return -1;  // 没有找到就返回-1
    }

    int find(const string& s, int pos = 0) const 
    {
      assert(pos >= 0 && pos < _size);
      char* tmp = strstr(_a + pos, s._a);
      if (tmp == NULL)
        return -1;
      return tmp - _a;
    }

    // 构造子串
    
    string substr(int pos, int len) const 
    {
      assert(pos >= 0 && pos < _size && len > 0);
      string tmp;
      int n = pos + len;
      if (n > _size)
        n = _size;
      int i = pos;
      while(i < n)
        tmp += _a[i++];

      return tmp;
    }
    // 运算符重载
    char operator[](int i) const
    {
      assert(i < _size && i >= 0);
      return _a[i];
    }

    // +=
    string& operator+=(char c)
    {
      push_back(c);  // 复用
      return *this;
    }

    string& operator+=(const string& s)
    {
      return append(s);  // 复用并且返回
    }

    // 清理数据
    void clear()
    {
      _size = 0;
      _a[0] = '\0';
    }

    bool empty() const 
    {
      return _size == 0;
    }

    int get_npos()
    {
      return npos;
    }
  private:
    int _size;
    int _capacity;
    char* _a;
    const static unsigned int npos = -1;
  };

// 重载流插入和流提取
  istream& operator>>(istream& in, string& s)
  {
    s.clear();
    char c[16] = {0};
    char tmp = in.get();
    int i = 0;
    while(tmp != '\n' && tmp != ' ')
    {
      c[i++] = tmp;
      if (i == 15)
      {
        c[15] = '\0';
        s.append(c);
        i = 0;
      }

      tmp = in.get();
    }
    s.append(c);
    return in;
  }
  
  ostream& operator<<(ostream& out, const string& s)
  {
    for (int i = 0; i < s.size(); ++i)
    {
      out << s[i];
    }
    return out;
  }

}
